package com.nowadays.mobile.mvp.presenter;

import android.os.Looper;
import android.util.Log;

import com.nowadays.mobile.MainApplication;
import com.nowadays.mobile.db.DbProvider;
import com.nowadays.mobile.model.FocusDayList;
import com.nowadays.mobile.mvp.model.Focus;
import com.nowadays.mobile.mvp.model.MainInteractor;
import com.nowadays.mobile.mvp.model.MainInteractorImpl;
import com.nowadays.mobile.mvp.presenter.executor.MainThread;
import com.nowadays.mobile.mvp.presenter.executor.MainThreadImpl;
import com.nowadays.mobile.mvp.view.MainView;
import com.nowadays.mobile.utils.CommonUtils;
import com.nowadays.mobile.utils.ConstsDefine;
import com.nowadays.mobile.utils.FocusUtils;
import com.nowadays.mobile.utils.SettingInfo;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

public class MainPresenterImpl implements MainPresenter {

  private MainView view;
  private MainInteractor interactor;
  protected MainThread mMainThread;

  public MainPresenterImpl(MainView view) {
    this.view = view;
    this.mMainThread = MainThreadImpl.getInstance();
    this.interactor = new MainInteractorImpl(mMainThread);
    this.interactor.initFocus();
  }

  @Override
  public void initVoice() {
    HashMap<Integer, Integer> mSoundMap = interactor.getVoiceInfo();
    if (mSoundMap != null && mSoundMap.size() > 0) {
      return;
    }
    interactor.initVoice();
  }

  @Override
  public void playTickSound() {
    Focus focus = interactor.getFocus();
    if (focus.isPlayTick()) {
      if (CommonUtils.mSoundPool != null) {
        float setVolume = CommonUtils.getCurrentVolume();
        if (CommonUtils.mTickStreamId != 0) {
          CommonUtils.mSoundPool.resume(CommonUtils.mTickStreamId);
        } else {
          CommonUtils.mTickStreamId = CommonUtils.mSoundPool.play(CommonUtils.mSoundMap.get(ConstsDefine.KEY_TICK_SOUND), setVolume, setVolume, 1, -1, 1);
        }
      }
    }
  }

  @Override
  public void pauseTickSound() {
    if (CommonUtils.mSoundPool != null) {
      CommonUtils.mSoundPool.pause(CommonUtils.mTickStreamId);
    }
  }

  private void resumePlayTick() {
    Focus focus = interactor.getFocus();
    byte focusBtnState = focus.getState();
    if (focusBtnState == ConstsDefine.STATE.FOCUS || focusBtnState == ConstsDefine.STATE.REST) {
      playTickSound();
    }
  }

  @Override
  public void playAlarmSound(boolean isFinish) {
    Focus focus = interactor.getFocus();
    if (focus.isPlayAlaram()) {
      if (CommonUtils.mSoundPool != null) {
        float setVolume = CommonUtils.getCurrentVolume();
        if (isFinish) {
          CommonUtils.mSoundPool.play(CommonUtils.mSoundMap.get(ConstsDefine.KEY_FINISH_ALARM_SOUND), setVolume, setVolume, 1, 0, 1);
        } else {
          CommonUtils.mSoundPool.play(CommonUtils.mSoundMap.get(ConstsDefine.KEY_REST_ALARM_SOUND), setVolume, setVolume, 1, 0, 1);
        }
      }
    }
  }

  @Override
  public int getRestTime() {
    return 0;
  }

  @Override
  public int getFocusTime() {
    return 0;
  }

  @Override
  public void showVibrate() {
    Focus focus = Focus.getInstance();
    if (focus.isVibrate()) {
      view.showVibrate();
    }
  }

  @Override
  public void switchFocus() {
    Focus focus = Focus.getInstance();
    byte focusState = focus.getState();
    if (focusState == ConstsDefine.STATE.FOCUS || focusState == ConstsDefine.STATE.REST) {
      view.cancelRestOrFocus();
      pauseTickSound();
      view.initShowTime(focus.getFocusTime());
      resetFocusTimes();
    } else if (focusState == ConstsDefine.STATE.NONE) {
      //开始时，保存此次专注时长
      int times = 0;
      if (focus.isAutoFocus()) {
        times = SettingInfo.getInstance().getFocusTimes(); //已经专注的次数
      }
      //如果不是自动专注也加1
      times++;
      updateFocusTimes(times);

      focus.setRunFocusTime(focus.getFocusTime());
      view.startRestOrFocus(focus.getFocusTime());
      playTickSound();
    }
    view.switchColorAndBtn(focusState);
  }

  private void updateFocusTimes(int times) {
    SettingInfo.getInstance().setFocusTimes(times);
  }

  @Override
  public void resetFocusTimes() {
    updateFocusTimes(0);
  }

  @Override
  public void updateFocusState(byte focusState) {
    Focus focus = Focus.getInstance();
    focus.setState(focusState);
  }

  @Override
  public void onFocusOrRestEnd() {
    Focus focus = Focus.getInstance();
    byte state = focus.getState();
    if (state == ConstsDefine.STATE.FOCUS) {
      //focus end auto,
      pauseTickSound();
      showVibrate();
//      focus.setState(ConstsDefine.STATE.FOCUS_END);
//      switchFocus();
      view.switchColorAndBtn(ConstsDefine.STATE.FOCUS_END);
      playAlarmSound(false);

      int focusTime = focus.getRunFocusTime();
      interactor.saveFocus(focusTime);

      List<FocusDayList> data = interactor.queryFocusList();
      view.updateFocusListData(data);

      view.cancelRestOrFocus();
      int restTime = focus.getRestTime();
      if (isLongRest(focus)) {
        restTime = focus.getLongRestTime();
      }
      view.initShowTime(restTime);
      view.onEnd(focus.getState(), restTime);

      final int finalRestTime = restTime;
      mMainThread.postDelayed(new Runnable() {
        @Override
        public void run() {
          view.startRestOrFocus(finalRestTime);
          playTickSound();
        }
      }, FocusUtils.MILLIS_IN_SECOND);
    } else if (state == ConstsDefine.STATE.REST) {
      pauseTickSound();
      playAlarmSound(true);
      showVibrate();
//      focus.setState(ConstsDefine.STATE.REST_END);
//      switchFocus();
      view.switchColorAndBtn(ConstsDefine.STATE.REST_END);

      int focusTime = focus.getFocusTime();
      view.initShowTime(focusTime);
      view.onEnd(focus.getState(), focus.getRunFocusTime());

      //如果是自动专注
      if (focus.isAutoFocus()) {
        int focusTimes = SettingInfo.getInstance().getFocusTimes();
        if (focusTimes < ConstsDefine.MAX_FOCUS_TIMES) {
          switchFocus();
        } else {
          resetFocusTimes();
        }
      } else {
        resetFocusTimes();
      }
    }
  }

  //是否需要开始长时休息
  private boolean isLongRest(Focus focus) {
    //如果是自动专注，则开始判断是否使用长时休息
    if (focus.isAutoFocus()) {
      int longRestDelay = focus.getLongRestDelay();
      int focusTimes = SettingInfo.getInstance().getFocusTimes();
      if (focusTimes % longRestDelay == 0) {
        return true;
      }
    }
    return false;
  }

  @Override
  public void resumeNotification() {
    byte state = getFocusState();
    if(state == ConstsDefine.STATE.FOCUS || state == ConstsDefine.STATE.REST) {
      view.resumeNotification();
    }
  }

  @Override
  public byte getFocusState() {
    Focus focus =Focus.getInstance();
    return focus.getState();
  }

  @Override
  public void onStart() {
    Focus focus = Focus.getInstance();
    byte state = focus.getState();
    Log.d("TAG", "onStart:state=" + state);
    if (state == ConstsDefine.STATE.NONE) {
      int focusTime = focus.getFocusTime();
      Log.d("TAG", "onStart:focusTime=" + focusTime);
      view.initShowTime(focusTime);

      ArrayList<com.nowadays.mobile.model.Focus> focusList = DbProvider.getInstance(MainApplication.getContext()).queryFocusList();
      List<FocusDayList> data = FocusUtils.listFocusByDay(focusList);
      view.updateFocusListData(data);
    }
  }

  @Override
  public void cancelNotification() {
    byte state = getFocusState();
    if(state == ConstsDefine.STATE.FOCUS || state == ConstsDefine.STATE.REST) {
      //cancel notification
      view.cancelNotification();
    }
  }

  @Override
  public void onRestart() {
    if (CommonUtils.mSoundPool == null || CommonUtils.mSoundMap == null) {
      initVoice();
    }
  }

  @Override
  public void onResume() {
    Log.d("TAG", "threadId:" + Thread.currentThread().getId() + ",isMainThread:" + (Looper.getMainLooper() == Looper.myLooper()));
    Focus focus = interactor.getFocus();
    boolean isPrevent = focus.isPreventScreen();
    if (isPrevent) {
      view.preventLockScreen(true);
    }
    resumePlayTick();
  }

  @Override
  public void onPause() {
    Focus focus = interactor.getFocus();
    boolean isPrevent = focus.isPreventScreen();
    if (isPrevent) {
      view.preventLockScreen(false);
    }
  }

  @Override
  public void onStop() {

  }

  @Override
  public void onDestroy() {
    if (CommonUtils.mSoundPool != null) {
      CommonUtils.mSoundPool.release();
      CommonUtils.mSoundPool = null;
    }
    view = null;
  }
}
